home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / MISC / BM192A.ZIP / BSPD.S < prev    next >
Encoding:
Text File  |  1996-02-23  |  21.8 KB  |  675 lines

  1. *=======================================================*
  2. *    BSP-Descent: latest update 23/02/96        *
  3. *=======================================================*
  4. *    Descend BSP tree, generating sectors & walls.    *
  5. *=======================================================*
  6.  
  7. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
  8. *    Descend Binary Space Partitioning Tree        *
  9. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
  10.     txtlong
  11. *-------------------------------------------------------*
  12. descend_bsp:
  13. *-------------------------------------------------------*
  14. *    Place start & terminator on heap and descend    *
  15. *-------------------------------------------------------*
  16.     move.l        sp,bsp_return
  17.     lea        display_struct,a6
  18.     push.w        #terminator
  19.     push.w        maxnode
  20.     bra        next_node
  21. *-------------------------------------------------------*
  22. *    Thread returns here when tree is exhausted    *
  23. *-------------------------------------------------------*
  24. finish_tree:
  25. *-------------------------------------------------------*
  26.     move.l        bsp_return,sp
  27.     rts
  28.  
  29. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
  30. *    [node] = [sector] -> draw this node        *
  31. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
  32.     txtlong
  33. *-------------------------------------------------------*
  34. ssector_node:
  35. *-------------------------------------------------------*
  36. *    Stop drawing when [width] columns are filled    *
  37. *-------------------------------------------------------*
  38.     tst.w        columns
  39.     beq.s        finish_tree
  40. *-------------------------------------------------------*
  41. *    Stop drawing when last node has been popped    *
  42. *-------------------------------------------------------*
  43.     not.w        d0
  44.     beq.s        finish_tree
  45.     eor.w        #$7FFF,d0
  46.     move.w        d0,ourssector        
  47.  
  48. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
  49. *    Render ssector into run-buffer            *
  50. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
  51. build_ssector:
  52. *-------------------------------------------------------*
  53. *    Locate [segs] for this [ssector]        *
  54. *-------------------------------------------------------*
  55.     move.l        display_ssectors(a6),a0
  56.     moveq        #0,d4
  57.     move.w        ssec_first(a0,d0.w*4),d4
  58.     moveq        #0,d3
  59.     move.w        ssec_segments(a0,d0.w*4),d3
  60. *-------------------------------------------------------*
  61. *    Locate [linedef] & [sidedef] for first [seg]    *
  62. *-------------------------------------------------------*
  63.     move.l        d4,d0
  64.     move.l        display_segs(a6),a2
  65.     add.l        d0,d0
  66.     add.l        d4,d0
  67.     lsl.l        #2,d0
  68.     add.l        d0,a2                ; a+(d*12)
  69.     moveq        #0,d0
  70.     move.w        seg_linedef(a2),d0
  71.     moveq        #0,d2
  72.     move.w        seg_sidedef(a2),d2
  73. *-------------------------------------------------------*
  74. *    Locate right [sidedef] for this [linedef]    *
  75. *-------------------------------------------------------*
  76.     move.l        d0,d1
  77.     move.l        display_linedefs(a6),a0
  78.     lsl.l        #3,d0
  79.     sub.l        d1,d0
  80.     add.l        d0,d0
  81.     add.l        d0,a0                ; a+(d*14)
  82.     moveq        #0,d1
  83.     move.w        linedef_right(a0,d2.w*2),d1 
  84. *-------------------------------------------------------*
  85. *    Locate [sector] for this [sidedef]        *
  86. *-------------------------------------------------------*
  87.     move.l        d1,d0 
  88.     move.l        display_sidedefs(a6),a0
  89.     lsl.l        #4,d0 
  90.     sub.l        d1,d0                ; a+(d*30)
  91.     move.w        sidedef_sector(a0,d0.l*2),d1    
  92. *-------------------------------------------------------*
  93. *    Set up floor & ceiling heights for this sector    *
  94. *-------------------------------------------------------*
  95.     move.l        d1,d0
  96.     add.l        d0,d0
  97.     move.l        d0,d2
  98.     lsl.l        #3,d0
  99.     move.l        display_sectors(a6),a0
  100.     sub.l        d2,d0
  101.     sub.l        d1,d0                ; a+(d*26)
  102.     add.l        d0,d0
  103.     add.l        d0,a0
  104.     move.l        a0,this_sector
  105.     move.w        sector_floorht(a0),floor_ht
  106.     move.w        sector_ceilht(a0),ceiling_ht
  107.     move.w        sector_ctns(a0),ceiling_texture
  108.     move.w        sector_ftns(a0),floor_texture
  109. *-------------------------------------------------------*
  110. *    Are we in this sector?                *
  111. *-------------------------------------------------------*
  112.     tst.b        first_ssector
  113.     beq.s        .skip
  114.     clr.b        first_ssector
  115. *-------------------------------------------------------*
  116. *    Set viewcone to (sector_height+player_height)    *
  117. *-------------------------------------------------------*
  118.     move.w        floor_ht,d0
  119.     add.w        #player_height,d0
  120.     add.w        pho,d0
  121.     move.w        d0,ph
  122. *-------------------------------------------------------*
  123. *    Set up segment-heap for loop            *
  124. *-------------------------------------------------------*
  125. .skip:    move.l        d4,d2
  126.     move.w        d2,display_segbase(a6)
  127.     move.w        d3,display_segnum(a6)
  128.     ble        next_node
  129. *-------------------------------------------------------*
  130.     move.w        ph,d1
  131.     sub.w        ceiling_ht,d1 
  132.     swap        d1
  133.     clr.w        d1
  134.     move.l        d1,ceiling_y
  135.     move.w        ph,d1
  136.     sub.w        floor_ht,d1 
  137.     swap        d1
  138.     clr.w        d1
  139.     move.l        d1,floor_y
  140. *-------------------------------------------------------*
  141. *    Process simple lighting effects (temporary!)    *
  142. *-------------------------------------------------------*
  143.     bsr        process_lighting
  144. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
  145. *    Render segments surrounding this ssector    *
  146. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
  147. segment_loop:
  148. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
  149. *    Hidden surface removal stage #1            *
  150. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
  151. *    Is viewer on left or right side of this line?    *
  152. *-------------------------------------------------------*
  153. *    ((y2-y1)*(x1-Px))) => (((x2-x1)*(y1-Py)) ?    *
  154. *-------------------------------------------------------*
  155.     move.l        display_vertices(a6),a0
  156.     moveq        #0,d0
  157.     moveq        #0,d1
  158.     move.w        linedef_from(a2),d0
  159.     move.w        linedef_to(a2),d1
  160.     move.w        vtx_x(a0,d0.l*4),d5
  161.     move.w        vtx_x(a0,d1.l*4),d6
  162.     move.w        vtx_y(a0,d0.l*4),d0
  163.     move.w        vtx_y(a0,d1.l*4),d1
  164.     sub.w        d5,d6            ; x2-x1
  165.     sub.w        d0,d1            ; y2-y1
  166.     sub.w        display_px(a6),d5    ; x1-px
  167.     sub.w        display_py(a6),d0    ; y1-py
  168.     muls.w        d6,d0            ; (x2-x1)*(y1-Py)
  169.     muls.w        d5,d1            ; (x1-px)*(y2-y1)
  170.     cmp.l        d0,d1
  171.     bpl        invisible
  172. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
  173. *    Segment is visible                *
  174. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
  175.     pea        (a2)
  176. *-------------------------------------------------------*
  177.     moveq        #0,d0
  178.     move.w        display_segbase(a6),d0
  179.     move.l        d0,d1
  180.     move.l        display_segs(a6),a5
  181.     add.l        d0,d0
  182.     add.l        d1,d0
  183.     lsl.l        #2,d0
  184.     add.l        d0,a5            ; a+(d*12)
  185. *-------------------------------------------------------*
  186. *    Locate segment vertices                *
  187. *-------------------------------------------------------*
  188.     move.w        seg_bam(a5),umag
  189.     move.w        seg_distance(a5),uoff
  190.     move.l        display_vertices(a6),a0
  191.     moveq        #0,d0
  192.     move.w        seg_from(a5),d0
  193.     move.l        a0,a1
  194.     moveq        #0,d1
  195.     move.w        seg_to(a5),d1 
  196.     lsl.l        #2,d0
  197.     lsl.l        #2,d1
  198.     add.l        d0,a0            ; a+(d*4)
  199.     add.l        d1,a1            ; a+(d*4)
  200. *-------------------------------------------------------*
  201. *    Fetch X1,Y1 / X2,Y2 & centre around viewpoint    *
  202. *-------------------------------------------------------*
  203.     move.w        display_px(a6),d1
  204.     move.w        display_py(a6),d7
  205.     move.w        vtx_x(a0),d4
  206.     move.w        vtx_y(a0),d5
  207.     move.w        vtx_x(a1),d6
  208.     move.w        vtx_y(a1),d2
  209.     sub.w        d1,d4        ; dx1
  210.     sub.w        d7,d5        ; dy1
  211.     sub.w        d1,d6        ; dx2
  212.     sub.w        d7,d2        ; dy2
  213. *-------------------------------------------------------*
  214. *    Rotate X & Y into canonical VX & VZ        *
  215. *-------------------------------------------------------*
  216.     move.w        display_sina(a6),d0
  217.     move.w        display_cosa(a6),d7
  218. *-------------------------------------------------------*
  219. *    x1 = (dx1)*sin(a) + (dy1)*cos(a)        *
  220. *    z1 = (dx1)*cos(a) - (dy1)*sin(a)        *
  221. *-------------------------------------------------------*
  222.     move.w        d4,d3
  223.     move.w        d5,d1
  224.     muls.w        d7,d4
  225.     muls.w        d0,d5
  226.     muls.w        d0,d3
  227.     muls.w        d7,d1
  228.     sub.l        d5,d4
  229.     add.l        d1,d3
  230. *-------------------------------------------------------*
  231. *    x2 = (dx2)*sin(a) + (dy2)*cos(a)        *
  232. *    z2 = (dx2)*cos(a) - (dy2)*sin(a)        *
  233. *-------------------------------------------------------*
  234.     move.w        d6,d5
  235.     move.w        d2,d1
  236.     muls.w        d7,d6
  237.     muls.w        d0,d2
  238.     muls.w        d0,d5
  239.     muls.w        d7,d1
  240.     sub.l        d2,d6
  241.     add.l        d1,d5
  242. *-------------------------------------------------------*
  243. *    Renormalize output from matrix            *
  244. *-------------------------------------------------------*
  245.     lsl.l        #2,d3        ; x1
  246.     lsl.l        #2,d4        ; z1
  247.     lsl.l        #2,d5        ; x2
  248.     lsl.l        #2,d6        ; z2
  249. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
  250. *    Z-clipping of walls                *
  251. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
  252.     lea        addwall_struct,a2
  253.     move.l        d6,addwall_rz1(a2)
  254.     move.l        d4,addwall_rz2(a2)
  255. *-------------------------------------------------------*
  256.     moveq        #ZMIN,d0
  257.     swap        d0
  258. *-------------------------------------------------------*
  259. *    Check for intersection with viewplane        *
  260. *-------------------------------------------------------*
  261.     cmp.l        d0,d4
  262.     bgt.s        .vis1
  263. *-------------------------------------------------------*
  264. *    Skip segment if both points are behind viewer    *
  265. *-------------------------------------------------------*
  266.     cmp.l        d0,d6
  267.     ble        end_segment
  268. *-------------------------------------------------------*
  269. *    Case #1 - clip X1,Z1 against ZMIN        *
  270. *-------------------------------------------------------*
  271.     sub.l        d4,d0        ; (cz-z1)
  272.     move.l        d5,d1
  273.     sub.l        d3,d1        ; (x2-x1)
  274.     muls.l        d0,d2:d1    ; (x2-x1)*(cz-z1)
  275.     move.l        d6,d0
  276.     sub.l        d4,d0        ; (z2-z1)
  277.     divs.l        d0,d2:d1    ; ((x2-x1)*(cz-z1))/(z2-z1)
  278.     add.l        d1,d3        ; (((x2-x1)*(cz-z1))/(z2-z1))+x1
  279.     moveq        #ZMIN,d4
  280.     swap        d4        ; z1 = cz
  281.     bra.s        .vis2
  282. *-------------------------------------------------------*
  283. *    Draw segment if both points are in view        *
  284. *-------------------------------------------------------*
  285. .vis1:    cmp.l        d0,d6
  286.     bgt.s        .vis2
  287. *-------------------------------------------------------*
  288. *    Case #2 - clip X2,Z2 against ZMIN        *
  289. *-------------------------------------------------------*
  290.     sub.l        d6,d0        ; (cz-z2)
  291.     move.l        d3,d1
  292.     sub.l        d5,d1        ; (x1-x2)
  293.     muls.l        d0,d2:d1    ; (x1-x2)*(cz-z2)
  294.     move.l        d4,d0
  295.     sub.l        d6,d0        ; (z1-z2)
  296.     divs.l        d0,d2:d1    ; ((x1-x2)*(cz-z2))/(z1-z2)
  297.     add.l        d1,d5        ; (((x1-x2)*(cz-z2))/(z1-z2))+x2
  298.     moveq        #ZMIN,d6
  299.     swap        d6        ; z2 = cz
  300. *-------------------------------------------------------*
  301. *    Project points into 2D viewspace        *
  302. *-------------------------------------------------------*
  303. .vis2:    moveq        #0,d1
  304.     move.w        display_hscale(a6),d1
  305.     swap        d1
  306.     muls.l        d1,d0:d3
  307.     divs.l        d4,d0:d3
  308.     muls.l        d1,d0:d5
  309.     divs.l        d6,d0:d5
  310.     move.l        d1,d0
  311.     add.l        d0,d0
  312. *-------------------------------------------------------*
  313. *    Centre screen coordinates & check bounds    *
  314. *-------------------------------------------------------*
  315.     neg.l        d5
  316.     add.l        d1,d5
  317.     ble        end_segment
  318.     move.l        d5,d7
  319.     cmp.l        d0,d7
  320.     bmi.s        .i2in
  321.     move.l        d0,d7    
  322. .i2in:    neg.l        d3
  323.     add.l        d1,d3
  324.     move.l        d3,d1
  325.     bpl.s        .i1in
  326.     moveq        #0,d1
  327. .i1in:    cmp.l        d0,d3
  328.     bpl        end_segment
  329. *-------------------------------------------------------*
  330. *    Check size (i2-i1)                *
  331. *-------------------------------------------------------*
  332.     swap        d1
  333.     swap        d7
  334.     move.w        d7,d0
  335.     sub.w        d1,d0
  336.     ble        end_segment
  337. *-------------------------------------------------------*
  338. *    Discard fully occluded walls            *
  339. *-------------------------------------------------------*
  340.     lea        DSPHostStat.w,a2
  341.     lea        DSPHost16.w,a0
  342.     moveq        #scan_command,d0
  343.     dspwaitwrite    (a2)
  344.     move.w        d0,(a0)                ; occlusion check command
  345.     dspwaitwrite    (a2)
  346.     move.w        d1,(a0)                ; wall i1
  347.     dspwaitwrite    (a2)
  348.     move.w        d7,(a0)                ; wall i2
  349.     dspwaitread    (a2)
  350.     tst.w        (a0)                ; result (visible y/n)
  351.     beq        end_segment
  352. *-------------------------------------------------------*
  353. *    Write coordinates into addwall struct        *
  354. *-------------------------------------------------------*
  355. .draw:    lea        addwall_struct,a2
  356.     move.l        d3,addwall_i1(a2)
  357.     move.l        d4,addwall_z1(a2)
  358.     move.l        d5,addwall_i2(a2)
  359.     move.l        d6,addwall_z2(a2)
  360. *-------------------------------------------------------*
  361. *    Look up linedef for this seg            *
  362. *-------------------------------------------------------*
  363.     moveq        #0,d1
  364.     move.w        seg_linedef(a5),d1
  365.     move.l        d1,d0 
  366.     move.l        display_linedefs(a6),a0
  367.     lsl.l        #3,d0 
  368.     sub.l        d1,d0
  369.     add.l        d0,d0
  370.     add.l        d0,a0
  371.     move.l        a0,a1
  372. *-------------------------------------------------------*
  373. *    Determine one or two-sided linedef        *
  374. *-------------------------------------------------------*
  375.     moveq        #attrib_twosided,d0
  376.     and.w        linedef_attrib(a0),d0
  377.     move.b        d0,twosided_flag
  378. *-------------------------------------------------------*
  379. *    Determine which sidedef is facing us        *
  380. *-------------------------------------------------------*
  381.     move.w        seg_sidedef(a5),d0
  382.     moveq        #0,d5
  383.     move.w        linedef_right(a0,d0.l*2),d5    ; visible sidedef
  384.     bchg        #0,d0
  385.     moveq        #0,d6
  386.     move.w        linedef_right(a0,d0.l*2),d6    ; invisible sidedef
  387. *-------------------------------------------------------*
  388. *    Look up sidedef for visible side of linedef    *
  389. *-------------------------------------------------------*
  390.     move.l        d5,d0
  391.     move.l        d0,d1
  392.     move.l        display_sidedefs(a6),a3
  393.     lsl.l        #4,d0
  394.     sub.l        d1,d0
  395.     add.l        d0,d0
  396.     add.l        d0,a3                ; a+(d*30)
  397. *-------------------------------------------------------*
  398. *    (a6) pointer to addwall structure        *
  399. *-------------------------------------------------------*
  400.     lea        addwall_struct,a6
  401. *-------------------------------------------------------*
  402. *    Check for main wall texture            *
  403. *-------------------------------------------------------*
  404.     tst.w        sidedef_mtns(a3) 
  405.     bmi.s        sector_window
  406. *-------------------------------------------------------*
  407. *    Valid texture indicates a solid sector wall    *
  408. *-------------------------------------------------------*
  409. sector_wall:    
  410. *-------------------------------------------------------*
  411.     move.b        twosided_flag,addwall_opaque(a6)
  412.     move.w        ph,d0
  413.     move.w        d0,d1
  414.     sub.w        ceiling_ht,d1
  415.     move.w        d0,d2
  416.     sub.w        floor_ht,d2
  417.     cmp.w        d1,d2
  418.     bmi        end_segment
  419.     move.w        d1,addwall_y1(a6)
  420.     move.w        d2,addwall_y2(a6)
  421.     move.b        #WALL_TYPE,addwall_type(a6)
  422.     bsr        add_wall_segment
  423.     bra        end_segment
  424. *-------------------------------------------------------*
  425. sector_window:
  426. *-------------------------------------------------------*
  427.     move.b        #0,addwall_opaque(a6)
  428. *-------------------------------------------------------*
  429. *    Locate [sector] on opposite side of [linedef]    *
  430. *-------------------------------------------------------*
  431.     move.l        d6,d0
  432.     move.l        Side_Array,a4
  433.     move.l        d0,d1
  434.     lsl.l        #4,d0
  435.     sub.l        d1,d0
  436.     move.w        sidedef_sector(a4,d0.l*2),a0    ; a+(d*30)
  437.     lea        (a0,a0.l*2),a2
  438.     move.l        Sector_Array,a1
  439.     move.l        a2,d0 
  440.     lsl.l        #2,d0
  441.     add.l        a0,d0
  442.     lea        (a1,d0.l*2),a4            ; a+(d*26)
  443. *-------------------------------------------------------*
  444. *    Check for lower wall texture            *
  445. *-------------------------------------------------------*
  446.     move.w        floor_ht,d1 
  447.     cmp.w        #-1,sidedef_ltns(a3) 
  448.     beq.s        lower_floor
  449.     bpl.s        lower_wall
  450.     move.w        #1000,d1
  451.     move.w        d1,d2
  452.     bra.s        lower_sky
  453. *-------------------------------------------------------*
  454. *    Valid texture indicates a solid lower wall    *
  455. *-------------------------------------------------------*
  456. lower_wall:
  457. *-------------------------------------------------------*
  458.     move.w        sector_floorht(a4),d1
  459.     cmp.w        ceiling_ht,d1
  460.     bmi.s        lower_floor
  461.     move.w        ceiling_ht,d1
  462. *-------------------------------------------------------*
  463. lower_floor:
  464. *-------------------------------------------------------*
  465.     move.w        floor_ht,d2 
  466.     neg.w        d1
  467.     neg.w        d2
  468. *-------------------------------------------------------*
  469. lower_sky:
  470. *-------------------------------------------------------*
  471.     add.w        ph,d1
  472.     add.w        ph,d2
  473.     cmp.w        d1,d2
  474.     bpl.s        .fix
  475.     move.w        d2,d1
  476. .fix:    move.w        d1,addwall_y1(a6)
  477.     move.w        d2,addwall_y2(a6)
  478.     move.b        #LOWER_TYPE,addwall_type(a6)
  479.     bsr        add_wall_segment 
  480.     tst.w        columns
  481.     beq.s        end_segment         
  482. *-------------------------------------------------------*
  483. *    Check for upper wall texture            *
  484. *-------------------------------------------------------*
  485.     move.w        ceiling_ht,d2 
  486.     cmp.w        #-1,sidedef_utns(a3) 
  487.     beq.s        upper_ceiling
  488.     bpl.s        upper_wall
  489.     move.w        #-1000,d1
  490.     move.w        d1,d2
  491.     bra.s        upper_sky
  492. *-------------------------------------------------------*
  493. *    Valid texture indicates a solid upper wall    *
  494. *-------------------------------------------------------*
  495. upper_wall:
  496. *-------------------------------------------------------*
  497.     move.w        sector_ceilht(a4),d2
  498.     cmp.w        floor_ht,d2
  499.     bpl.s        upper_ceiling
  500.     move.w        floor_ht,d2
  501. *-------------------------------------------------------*
  502. upper_ceiling:
  503. *-------------------------------------------------------*
  504.     move.w        ceiling_ht,d1 
  505.     neg.w        d1
  506.     neg.w        d2
  507. *-------------------------------------------------------*
  508. upper_sky:
  509. *-------------------------------------------------------*
  510.     add.w        ph,d1
  511.     add.w        ph,d2
  512.     cmp.w        d1,d2
  513.     bpl.s        .fix
  514.     move.w        d1,d2
  515. .fix:    move.w        d1,addwall_y1(a6)
  516.     move.w        d2,addwall_y2(a6)
  517.     move.b        #UPPER_TYPE,addwall_type(a6)
  518.     bsr        add_wall_segment 
  519. *-------------------------------------------------------*
  520. end_segment:
  521. *-------------------------------------------------------*
  522.     pop.l        a2
  523. *-------------------------------------------------------*
  524. *    Proceed to next segment                *
  525. *-------------------------------------------------------*
  526. invisible:
  527. *-------------------------------------------------------*
  528.     lea        display_struct,a6
  529.     lea        seg_len(a2),a2
  530.     addq.w        #1,display_segbase(a6)
  531.     subq.w        #1,display_segnum(a6)
  532.     beq        end_ssector
  533.     tst.w        columns
  534.     bne        segment_loop
  535. *-------------------------------------------------------*
  536. end_ssector:
  537. *-------------------------------------------------------*
  538.     bsr        get_ssector
  539. *-------------------------------------------------------*
  540. *    Fetch next node from heap and descend again    *
  541. *-------------------------------------------------------*
  542. next_node:
  543. *-------------------------------------------------------*
  544.     move.w        (sp)+,d0
  545.     bmi        ssector_node
  546.  
  547. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
  548. *    [node] /= [sector] -> descend again        *
  549. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
  550. dividing_node:
  551. *-------------------------------------------------------*
  552.     move.l        display_nodes(a6),a1    
  553.     move.l        (a1,d0.w*4),a1
  554. *-------------------------------------------------------*
  555. *    Inverse descent rules for left side of tree    *
  556. *-------------------------------------------------------*
  557. *    (dy*(x1-Px))) => ((dx*(y1-Py)) ?        *
  558. *-------------------------------------------------------*
  559.     move.w        node_dx(a1),d2
  560.     move.w        node_x(a1),d0
  561.     move.w        node_dy(a1),d3
  562.     move.w        node_y(a1),d1
  563.     add.w        d2,d0            ; x2 = (x1+dx)
  564.     sub.w        display_px(a6),d0    ; (x2-px)
  565.     add.w        d3,d1            ; y2 = (y1+dy)
  566.     sub.w        display_py(a6),d1    ; (xy-py)
  567.     muls.w        d2,d1            ; (y2-py) * dx
  568.     muls.w        d3,d0            ; (x2-px) * dy
  569.     cmp.l        d0,d1 
  570.     bmi.s        node_leftside
  571. *-------------------------------------------------------*
  572. *    Viewer is on right side of node divider        *
  573. *-------------------------------------------------------*
  574. node_rightside:
  575. *-------------------------------------------------------*
  576.     lea        node_lvtx(a1),a0
  577.     bsr.s        nodeincone
  578.     beq.s        .noln
  579.     move.w        node_left(a1),-(sp)
  580. .noln:    lea        node_rvtx(a1),a0
  581.     bsr.s        nodeincone
  582.     beq.s        next_node
  583.     move.w        node_right(a1),-(sp) 
  584.     bra.s        next_node
  585. *-------------------------------------------------------*
  586. *    Viewer is on left side of node divider        *
  587. *-------------------------------------------------------*
  588. node_leftside:
  589. *-------------------------------------------------------*
  590.     lea        node_rvtx(a1),a0
  591.     bsr.s        nodeincone
  592.     beq.s        .noln
  593.     move.w        node_right(a1),-(sp) 
  594. .noln:    lea        node_lvtx(a1),a0
  595.     bsr.s        nodeincone
  596.     beq.s        next_node
  597.     move.w        node_left(a1),-(sp)
  598.     bra.s        next_node
  599.  
  600. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
  601. *    Determine visibility of a child node.        *
  602. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
  603. *    Only exposed nodes are dealt with.        *
  604. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
  605.  
  606. *-------------------------------------------------------*
  607. *    Check #1 -> Octal node elimination        * 
  608. *-------------------------------------------------------*
  609. *    All nodes are checked against the 3 octal    *
  610. *    segments immediately in front of viewcone.    *
  611. *    Nodes from 5 of all 8 octants are discarded.    *
  612. *-------------------------------------------------------*
  613. *    Check #2 -> Canonical volume intersection    * 
  614. *-------------------------------------------------------*
  615. *    The remaining nodes are fully intersected    *
  616. *    with the projected canonical view volume.    *
  617. *    Any nodes outside the viewcone are discarded.    *
  618. *-------------------------------------------------------*
  619. *    Check #3 -> Occlusion check            * 
  620. *-------------------------------------------------------*
  621. *    Any nodes remaining in view are checked        *
  622. *    against the occlusion table. Any nodes        *
  623. *    completely occluded by walls are discarded.    *
  624. *-------------------------------------------------------*
  625.     txtlong
  626. *-------------------------------------------------------*
  627. *    This function is now completely DSP based    *
  628. *-------------------------------------------------------*
  629. nodeincone:
  630. *-------------------------------------------------------*
  631.     lea        DSPHostStat.w,a2
  632.     lea        DSPHost16.w,a3
  633.     move.l        a0,a4
  634.     moveq        #nodeincone_command,d0
  635.     dspwaitwrite    (a2)
  636.     move.w        d0,(a3)
  637.     move.w        (a4)+,d0
  638.     dspwaitwrite    (a2)
  639.     move.w        d0,(a3)
  640.     move.w        (a4)+,d0
  641.     dspwaitwrite    (a2)
  642.     move.w        d0,(a3)
  643.     move.w        (a4)+,d0
  644.     dspwaitwrite    (a2)
  645.     move.w        d0,(a3)
  646.     move.w        (a4)+,d0
  647.     dspwaitwrite    (a2)
  648.     move.w        d0,(a3)
  649.     dspwaitread    (a2)
  650.     move.w        (a3),d0
  651.     tst.b        d0
  652.     rts
  653.  
  654. *-------------------------------------------------------*
  655.             bsslong
  656. *-------------------------------------------------------*
  657.  
  658. maxnode:        ds.l    1        ; last node index
  659. this_sector:        ds.l    1        ; current sector ptr
  660. bsp_return:        ds.l    1        ; BSP stack base
  661.  
  662. floor_ht:        ds.w    1        ; floor height (16.16)
  663. ceiling_ht:        ds.w    1        ; ceiling height (16.16)
  664. ceiling_texture:    ds.w    1        ; ceiling texture index
  665. floor_texture:        ds.w    1        ; floor texture index
  666. uoff:            ds.w    1        ; texture u-offset (xoff)
  667. ourssector:        ds.w    1        ; index of our sector
  668.  
  669. first_ssector:        ds.b    1        ; sector first-hit flag
  670. twosided_flag:        ds.b    1        ; transparent wall flag
  671.             
  672. *-------------------------------------------------------*
  673.             txtlong
  674. *-------------------------------------------------------*
  675.